package ph.com.gs3.chat;

import java.util.List;

import ph.com.gs3.chat.fragments.view.ChatViewFragment;
import ph.com.gs3.chat.fragments.view.ChatViewFragment.ChatViewActionListener;
import ph.com.gs3.chat.managers.PendingMessagesManager;
import ph.com.gs3.chat.managers.RealTimeEventsManager;
import ph.com.gs3.chat.model.valueobject.business.Message;
import ph.com.gs3.chat.model.valueobject.business.UserStub;
import ph.com.gs3.chat.services.NotifierService;
import ph.com.gs3.chat.utilities.FLLogger;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class ChatActivity extends Activity implements ChatViewActionListener {

	public static final String TAG = ChatActivity.class.getSimpleName();

	public static final String EXTRA_CURRENT_USER_STUB = "current_user_stub";
	public static final String EXTRA_USER_STUB = "user_stub";

	private ChatViewFragment viewFragment;

	private UserStub currentUser;
	private UserStub recipientUser;

	// =========================================================================
	// {{ Activity Life Cycle Listeners

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_chat);

		initializeFieldsFromExtras();
		initializeFragments(savedInstanceState);

		registerBroadcastReceiver();

		setTitle(recipientUser.getDisplayName());

		displayPendingMessages();

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.chat, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		unregisterReceiver(messageBroadcastReceiver);
	}

	// }}

	// =========================================================================
	// {{ Initializers

	private void initializeFieldsFromExtras() {

		Bundle extras = getIntent().getExtras();
		currentUser = (UserStub) extras.getSerializable(EXTRA_CURRENT_USER_STUB);
		recipientUser = (UserStub) extras.getSerializable(EXTRA_USER_STUB);

	}

	private void initializeFragments(Bundle savedInstanceState) {

		if (savedInstanceState == null) {
			viewFragment = new ChatViewFragment();
		}

		viewFragment.setConversationParticipants(currentUser, recipientUser);
		getFragmentManager().beginTransaction().add(R.id.container, viewFragment).commit();

	}

	private void displayPendingMessages() {

		List<String> pendingMessages = PendingMessagesManager.getDefaultInstance()
		        .getPendingMessages(recipientUser.getId());

		if (pendingMessages != null) {
			for (String message : pendingMessages) {
				viewFragment.addReceivedMessage(message);
			}

			PendingMessagesManager.getDefaultInstance().clearPendingMessage(recipientUser.getId());
		}

	}

	// }}

	@Override
	public void onSendMessageCommand(String message) {
		RealTimeEventsManager.getDefaultInstance().sendMessage(recipientUser.getId(), message);
	}

	private void registerBroadcastReceiver() {
		IntentFilter nlServiceFilter = new IntentFilter();
		nlServiceFilter.addAction(NotifierService.ACTION_ON_MESSAGE_RECEIVED);
		nlServiceFilter.addCategory(Intent.CATEGORY_DEFAULT);
		registerReceiver(messageBroadcastReceiver, nlServiceFilter);
	}

	private BroadcastReceiver messageBroadcastReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {

			String action = intent.getAction();

			if (NotifierService.ACTION_ON_MESSAGE_RECEIVED.equals(action)) {
				Message message = (Message) intent.getExtras().getSerializable(
				        NotifierService.EXTRA_RECIEVED_MESSAGE);

				FLLogger.d(TAG, "Message received from: " + message.getAuthor().getId() + " "
				        + message.getAuthor().getDisplayName());

				if (recipientUser.getId().equals(message.getAuthor().getId())) {
					viewFragment.addReceivedMessage(message.getMessage());
				}

			}

		}

	};

}
